{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# <center>手写数字分类识别入门体验教程</center>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 实现一个图片分类应用\n",
    "## 概述\n",
    "下面我们通过一个实际样例，带领大家体验MindSpore基础的功能，对于一般的用户而言，完成整个样例实践会持续20~30分钟。\n",
    "\n",
    "本例子会实现一个简单的图片分类的功能，整体流程如下：\n",
    "\n",
    "1. 处理需要的数据集，这里使用了MNIST数据集。\n",
    "\n",
    "2. 定义一个网络，这里我们使用LeNet网络。\n",
    "\n",
    "3. 定义损失函数和优化器。\n",
    "\n",
    "4. 加载数据集并进行训练，训练完成后，查看结果及保存模型文件。\n",
    "\n",
    "5. 加载保存的模型，进行推理。\n",
    "\n",
    "6. 验证模型，加载测试数据集和训练后的模型，验证结果精度。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "说明：<br/>你可以在这里找到完整可运行的样例代码：<https://gitee.com/mindspore/docs/blob/master/tutorials/tutorial_code/lenet.py>。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 训练的数据集下载"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 方法一：\n",
    "从以下网址下载，并将数据包解压缩后放至Jupyter的工作目录下：<br/>训练数据集：{\"<http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz>\", \"<http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz>\"}\n",
    "<br/>测试数据集：{\"<http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz>\", \"<http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz>\"}<br/>我们用下面代码查询jupyter的工作目录。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'C:\\\\Users\\\\Administrator'"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "os.getcwd()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练数据集放在----`Jupyter工作目录+\\MNIST_Data\\train\\`，此时train文件夹内应该包含两个文件，`train-images-idx3-ubyte`和`train-labels-idx1-ubyte` <br/>测试数据集放在----`Jupyter工作目录+\\MNIST_Data\\test\\`，此时test文件夹内应该包含两个文件，`t10k-images-idx3-ubyte`和`t10k-labels-idx1-ubyte`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 方法二：\n",
    "直接执行下面代码，会自动进行训练集的下载与解压，但是整个过程根据网络好坏情况会需要花费几分钟时间。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "******Downloading the MNIST dataset******\n"
     ]
    }
   ],
   "source": [
    "import urllib.request   \n",
    "from urllib.parse import urlparse\n",
    "import gzip \n",
    "\n",
    "def unzipfile(gzip_path):\n",
    "    \"\"\"unzip dataset file\n",
    "    Args:\n",
    "        gzip_path: dataset file path\n",
    "    \"\"\"\n",
    "    open_file = open(gzip_path.replace('.gz',''), 'wb')\n",
    "    gz_file = gzip.GzipFile(gzip_path)\n",
    "    open_file.write(gz_file.read())\n",
    "    gz_file.close()\n",
    "    \n",
    "def download_dataset():\n",
    "    \"\"\"Download the dataset from http://yann.lecun.com/exdb/mnist/.\"\"\"\n",
    "    print(\"******Downloading the MNIST dataset******\")\n",
    "    train_path = \"./MNIST_Data/train/\" \n",
    "    test_path = \"./MNIST_Data/test/\"\n",
    "    train_path_check = os.path.exists(train_path)\n",
    "    test_path_check = os.path.exists(test_path)\n",
    "    if train_path_check == False and test_path_check == False:\n",
    "        os.makedirs(train_path)\n",
    "        os.makedirs(test_path)\n",
    "    train_url = {\"http://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz\", \"http://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz\"}\n",
    "    test_url = {\"http://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz\", \"http://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gz\"}\n",
    "    \n",
    "    for url in train_url:\n",
    "        url_parse = urlparse(url)\n",
    "        # split the file name from url\n",
    "        file_name = os.path.join(train_path,url_parse.path.split('/')[-1])\n",
    "        if not os.path.exists(file_name.replace('.gz', '')):\n",
    "            file = urllib.request.urlretrieve(url, file_name)\n",
    "            unzipfile(file_name)\n",
    "            os.remove(file_name)\n",
    "            \n",
    "    for url in test_url:\n",
    "        url_parse = urlparse(url)\n",
    "        # split the file name from url\n",
    "        file_name = os.path.join(test_path,url_parse.path.split('/')[-1])\n",
    "        if not os.path.exists(file_name.replace('.gz', '')):\n",
    "            file = urllib.request.urlretrieve(url, file_name)\n",
    "            unzipfile(file_name)\n",
    "            os.remove(file_name)\n",
    "\n",
    "download_dataset()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这样就完成了数据集的下载解压缩工作。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 处理MNIST数据集"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "由于我们后面会采用LeNet这样的卷积神经网络对数据集进行训练，而采用LeNet在训练数据时，对数据格式是有所要求的，所以接下来的工作需要我们先查看数据集内的数据是什么样的，这样才能构造一个针对性的数据转换函数，将数据集数据转换成符合训练要求的数据形式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "更多的LeNet网络的介绍不在此赘述，希望详细了解LeNet网络，可以查询<http://yann.lecun.com/exdb/lenet/>。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 查看原始数据集数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The type of mnist_ds: <class 'mindspore.dataset.engine.datasets.MnistDataset'>\n",
      "Number of pictures contained in the mnist_ds： 60000\n",
      "The item of mnist_ds: dict_keys(['image', 'label'])\n",
      "Tensor of image in item: (28, 28, 1)\n",
      "The label of item: 9\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from mindspore import context\n",
    "import matplotlib.pyplot as plt\n",
    "import matplotlib\n",
    "import numpy as np\n",
    "import mindspore.dataset as ds\n",
    "\n",
    "context.set_context(mode=context.GRAPH_MODE, device_target=\"CPU\") \n",
    "train_data_path = \"./MNIST_Data/train\"\n",
    "test_data_path = \"./MNIST_Data/test\"\n",
    "mnist_ds = ds.MnistDataset(train_data_path)\n",
    "print('The type of mnist_ds:', type(mnist_ds))\n",
    "print(\"Number of pictures contained in the mnist_ds：\",mnist_ds.get_dataset_size())\n",
    "\n",
    "dic_ds = mnist_ds.create_dict_iterator()\n",
    "item = dic_ds.get_next()\n",
    "img = item[\"image\"]\n",
    "label = item[\"label\"]\n",
    "\n",
    "print(\"The item of mnist_ds:\", item.keys())\n",
    "print(\"Tensor of image in item:\", img.shape) \n",
    "print(\"The label of item:\", label)\n",
    "\n",
    "plt.imshow(np.squeeze(img))\n",
    "plt.title(\"number:%s\"% item[\"label\"])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从上面的运行情况我们可以看到,训练数据集`train-images-idx3-ubyte`和`train-labels-idx1-ubyte`对应的是6万张图片和6万个数字下标，载入数据后经过`create_dict_iterator`转换字典型的数据集，取其中的一个数据查看，这是一个key为`image`和`label`的字典，其中的`image`的张量(高度28，宽度28，通道1)和`label`为对应图片的数字。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据处理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数据集对于训练非常重要，好的数据集可以有效提高训练精度和效率，在加载数据集前，我们通常会对数据集进行一些处理。\n",
    "#### 定义数据集及数据操作\n",
    "我们定义一个函数`create_dataset`来创建数据集。在这个函数中，我们定义好需要进行的数据增强和处理操作：\n",
    "1. 定义数据集。\n",
    "2. 定义进行数据增强和处理所需要的一些参数。\n",
    "3. 根据参数，生成对应的数据增强操作。\n",
    "4. 使用`map`映射函数，将数据操作应用到数据集。\n",
    "5. 对生成的数据集进行处理。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mindspore.dataset.transforms.vision.c_transforms as CV\n",
    "import mindspore.dataset.transforms.c_transforms as C\n",
    "from mindspore.dataset.transforms.vision import Inter\n",
    "from mindspore.common import dtype as mstype\n",
    "\n",
    "\n",
    "def create_dataset(data_path, batch_size=32, repeat_size=1,\n",
    "                   num_parallel_workers=1):\n",
    "    \"\"\" create dataset for train or test\n",
    "    Args:\n",
    "        data_path (str): Data path\n",
    "        batch_size (int): The number of data records in each group\n",
    "        repeat_size (int): The number of replicated data records\n",
    "        num_parallel_workers (int): The number of parallel workers\n",
    "    \"\"\"\n",
    "    # define dataset\n",
    "    mnist_ds = ds.MnistDataset(data_path)\n",
    "\n",
    "    # define some parameters needed for data enhancement and rough justification\n",
    "    resize_height, resize_width = 32, 32\n",
    "    rescale = 1.0 / 255.0\n",
    "    shift = 0.0\n",
    "    rescale_nml = 1 / 0.3081\n",
    "    shift_nml = -1 * 0.1307 / 0.3081\n",
    "\n",
    "    # according to the parameters, generate the corresponding data enhancement method\n",
    "    resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR)\n",
    "    rescale_nml_op = CV.Rescale(rescale_nml, shift_nml)\n",
    "    rescale_op = CV.Rescale(rescale, shift)\n",
    "    hwc2chw_op = CV.HWC2CHW()\n",
    "    type_cast_op = C.TypeCast(mstype.int32)\n",
    "\n",
    "    # using map to apply operations to a dataset\n",
    "    mnist_ds = mnist_ds.map(input_columns=\"label\", operations=type_cast_op, num_parallel_workers=num_parallel_workers)\n",
    "    mnist_ds = mnist_ds.map(input_columns=\"image\", operations=resize_op, num_parallel_workers=num_parallel_workers)\n",
    "    mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_op, num_parallel_workers=num_parallel_workers)\n",
    "    mnist_ds = mnist_ds.map(input_columns=\"image\", operations=rescale_nml_op, num_parallel_workers=num_parallel_workers)\n",
    "    mnist_ds = mnist_ds.map(input_columns=\"image\", operations=hwc2chw_op, num_parallel_workers=num_parallel_workers)\n",
    "    \n",
    "    # process the generated dataset\n",
    "    buffer_size = 10000\n",
    "    mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size)\n",
    "    mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)\n",
    "    mnist_ds = mnist_ds.repeat(repeat_size)\n",
    "\n",
    "    return mnist_ds\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其中\n",
    "- `batch_size`：每组包含的数据个数，现设置每组包含32个数据。\n",
    "- `repeat_size`：数据集复制的数量。\n",
    "\n",
    "先进行`shuffle`、`batch`操作，再进行`repeat`操作，这样能保证1个`epoch`内数据不重复。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来我们查看将要进行训练的数据集内容是什么样的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "首先，查看数据集内包含多少组数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of groups in the dataset: 1875\n"
     ]
    }
   ],
   "source": [
    "datas = create_dataset(train_data_path)\n",
    "print('Number of groups in the dataset:', datas.get_dataset_size())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "其次，取出其中一组数据，查看包含的`key`，图片数据的张量，以及下标`labels`的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dict_keys(['label', 'image'])\n",
      "Tensor of image: (32, 1, 32, 32)\n",
      "labels: [7 4 0 6 6 6 5 8 3 5 4 8 5 3 2 9 3 7 3 0 9 2 0 6 3 3 6 2 5 9 2 0]\n"
     ]
    }
   ],
   "source": [
    "data = datas.create_dict_iterator().get_next()\n",
    "print(data.keys())\n",
    "images = data[\"image\"] \n",
    "labels = data[\"label\"] \n",
    "print('Tensor of image:', images.shape)\n",
    "print('labels:', labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "最后，查看`image`的图像和下标对应的值。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 32 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "count = 1\n",
    "for i in images:\n",
    "    plt.subplot(4, 8, count) \n",
    "    plt.imshow(np.squeeze(i))\n",
    "    plt.title('num:%s'%labels[count-1])\n",
    "    plt.xticks([])\n",
    "    count += 1\n",
    "    plt.axis(\"off\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过上述三个查询操作，看到经过变换后的图片，数据集内分成了1875组数据，每组数据中含有32张图片，每张图片像数值为32×32，数据全部准备好后，就可以进行下一步的数据训练了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 构造神经网络"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在对手写字体识别上，通常采用卷积神经网络架构（CNN）进行学习预测，最经典的属1998年由Yann LeCun创建的LeNet5架构，<br/>其中分为：<br/>1、输入层；<br/>2、卷积层C1；<br/>3、池化层S2；<br/>4、卷积层C3；<br/>5、池化层S4；<br/>6、全连接F6；<br/>7、全连接；<br/>8、全连接OUTPUT。<br/>结构示意如下图:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LeNet5结构图"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<img src=\"https://www.mindspore.cn/tutorial/zh-CN/master/_images/LeNet_5.jpg\" alt=\"LeNet5\">"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在构建LeNet5前，我们需要对全连接层以及卷积层进行初始化。\n",
    "\n",
    "`TruncatedNormal`：参数初始化方法，MindSpore支持`TruncatedNormal`、`Normal`、`Uniform`等多种参数初始化方法，具体可以参考MindSpore API的`mindspore.common.initializer`模块说明。\n",
    "\n",
    "初始化示例代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "import mindspore.nn as nn\n",
    "from mindspore.common.initializer import TruncatedNormal\n",
    "\n",
    "# initialize 2D convolution function\n",
    "def conv(in_channels, out_channels, kernel_size, stride=1, padding=0):\n",
    "    \"\"\"Conv layer weight initial.\"\"\"\n",
    "    weight = weight_variable()\n",
    "    return nn.Conv2d(in_channels, out_channels,\n",
    "                     kernel_size=kernel_size, stride=stride, padding=padding,\n",
    "                     weight_init=weight, has_bias=False, pad_mode=\"valid\")\n",
    "\n",
    "# initialize full connection layer\n",
    "def fc_with_initialize(input_channels, out_channels):\n",
    "    \"\"\"Fc layer weight initial.\"\"\"\n",
    "    weight = weight_variable()\n",
    "    bias = weight_variable()\n",
    "    return nn.Dense(input_channels, out_channels, weight, bias)\n",
    "\n",
    "# set truncated normal distribution\n",
    "def weight_variable():\n",
    "    \"\"\"Weight initial.\"\"\"\n",
    "    return TruncatedNormal(0.02)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用MindSpore定义神经网络需要继承`mindspore.nn.cell.Cell`，`Cell`是所有神经网络（`Conv2d`等）的基类。\n",
    "\n",
    "神经网络的各层需要预先在`__init__`方法中定义，然后通过定义`construct`方法来完成神经网络的前向构造，按照LeNet5的网络结构，定义网络各层如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "class LeNet5(nn.Cell):\n",
    "    \"\"\"Lenet network structure.\"\"\"\n",
    "    # define the operator required\n",
    "    def __init__(self):\n",
    "        super(LeNet5, self).__init__()\n",
    "        self.batch_size = 32\n",
    "        self.conv1 = conv(1, 6, 5)\n",
    "        self.conv2 = conv(6, 16, 5)\n",
    "        self.fc1 = fc_with_initialize(16 * 5 * 5, 120)\n",
    "        self.fc2 = fc_with_initialize(120, 84)\n",
    "        self.fc3 = fc_with_initialize(84, 10)\n",
    "        self.relu = nn.ReLU()\n",
    "        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        self.flatten = nn.Flatten()\n",
    "\n",
    "    # use the preceding operators to construct networks\n",
    "    def construct(self, x):\n",
    "        x = self.conv1(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.max_pool2d(x)\n",
    "        x = self.conv2(x) \n",
    "        x = self.relu(x)\n",
    "        x = self.max_pool2d(x)\n",
    "        x = self.flatten(x)\n",
    "        x = self.fc1(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.fc2(x)\n",
    "        x = self.relu(x)\n",
    "        x = self.fc3(x) \n",
    "        return x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构建完成后，我们将LeNet5的整体参数打印出来查看一下。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LeNet5<\n",
       "  (conv1): Conv2d<input_channels=1, output_channels=6, kernel_size=(5, 5),stride=(1, 1),  pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False,weight_init=Parameter (name=conv1.weight), bias_init=None>\n",
       "  (conv2): Conv2d<input_channels=6, output_channels=16, kernel_size=(5, 5),stride=(1, 1),  pad_mode=valid, padding=0, dilation=(1, 1), group=1, has_bias=False,weight_init=Parameter (name=conv2.weight), bias_init=None>\n",
       "  (fc1): Dense<in_channels=400, out_channels=120, weight=Parameter (name=fc1.weight), has_bias=True, bias=Parameter (name=fc1.bias)>\n",
       "  (fc2): Dense<in_channels=120, out_channels=84, weight=Parameter (name=fc2.weight), has_bias=True, bias=Parameter (name=fc2.bias)>\n",
       "  (fc3): Dense<in_channels=84, out_channels=10, weight=Parameter (name=fc3.weight), has_bias=True, bias=Parameter (name=fc3.bias)>\n",
       "  (relu): ReLU<>\n",
       "  (max_pool2d): MaxPool2d<kernel_size=2, stride=2, pad_mode=VALID>\n",
       "  (flatten): Flatten<>\n",
       "  >"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "network = LeNet5()\n",
    "network"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Parameter (name=conv1.weight),\n",
       " Parameter (name=conv2.weight),\n",
       " Parameter (name=fc1.weight),\n",
       " Parameter (name=fc1.bias),\n",
       " Parameter (name=fc2.weight),\n",
       " Parameter (name=fc2.bias),\n",
       " Parameter (name=fc3.weight),\n",
       " Parameter (name=fc3.bias)]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "param = network.trainable_params()\n",
    "param"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 搭建训练网络并进行训练"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构建完成神经网络后，就可以着手进行训练网络的构建，模型训练函数为`Model.train`，参数主要包含：\n",
    "1. 每个`epoch`需要遍历完成图片的`batch`数：`epoch_size`；\n",
    "2. 数据集`ds_train`；\n",
    "3. 回调函数`callbacks`包含`ModelCheckpoint`、`LossMonitor`和`Callback`模型检测参数；\n",
    "4. 数据下沉模式`dataset_sink_mode`，此参数默认`True`需设置成`False`，因为此功能不支持CPU模式。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# training related modules\n",
    "from mindspore import Tensor\n",
    "from mindspore.train.serialization import load_checkpoint, load_param_into_net\n",
    "from mindspore.train.callback import ModelCheckpoint, CheckpointConfig, LossMonitor,Callback\n",
    "from mindspore.train import Model\n",
    "from mindspore.nn.metrics import Accuracy\n",
    "\n",
    "def train_net(model, epoch_size, mnist_path, repeat_size, ckpoint_cb, step_loss_info):\n",
    "    \"\"\"Define the training method.\"\"\"\n",
    "    print(\"============== Starting Training ==============\")\n",
    "    # load training dataset\n",
    "    ds_train = create_dataset(os.path.join(mnist_path, \"train\"), 32, repeat_size)\n",
    "    model.train(epoch_size, ds_train, callbacks=[ckpoint_cb, LossMonitor(125), step_loss_info], dataset_sink_mode=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "自定义一个存储每一步训练的`step`和对应loss值的类`Step_loss_info`，并继承了`Callback`类，可以自定义训练过程中的处理措施，非常方便，等训练完成后，可将数据绘图查看loss的变化情况。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# custom callback function\n",
    "class StepLossInfo(Callback):\n",
    "    def step_end(self, run_context):\n",
    "        cb_params = run_context.original_args()\n",
    "        # step_loss dictionary for saving loss value and step number information\n",
    "        step_loss[\"loss_value\"].append(str(cb_params.net_outputs))\n",
    "        step_loss[\"step\"].append(str(cb_params.cur_step_num))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义损失函数及优化器\n",
    "\n",
    "在进行定义之前，先简单介绍损失函数及优化器的概念。\n",
    "\n",
    "损失函数：又叫目标函数，用于衡量预测值与实际值差异的程度。深度学习通过不停地迭代来缩小损失函数的值。定义一个好的损失函数，可以有效提高模型的性能。\n",
    "\n",
    "优化器：用于最小化损失函数，从而在训练过程中改进模型。\n",
    "\n",
    "定义了损失函数后，可以得到损失函数关于权重的梯度。梯度用于指示优化器优化权重的方向，以提高模型性能。\n",
    "\n",
    "MindSpore支持的损失函数有`SoftmaxCrossEntropyWithLogits`、`L1Loss`、`MSELoss`等。这里使用`SoftmaxCrossEntropyWithLogits`损失函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "============== Starting Training ==============\n",
      "epoch: 1 step 125, loss is 2.3136098384857178\n",
      "epoch: 1 step 250, loss is 2.303882598876953\n",
      "epoch: 1 step 375, loss is 2.3046326637268066\n",
      "epoch: 1 step 500, loss is 2.3024802207946777\n",
      "epoch: 1 step 625, loss is 2.3106091022491455\n",
      "epoch: 1 step 750, loss is 2.298833131790161\n",
      "epoch: 1 step 875, loss is 2.3070852756500244\n",
      "epoch: 1 step 1000, loss is 2.284291982650757\n",
      "epoch: 1 step 1125, loss is 0.7130898237228394\n",
      "epoch: 1 step 1250, loss is 0.17307262122631073\n",
      "epoch: 1 step 1375, loss is 0.3248927891254425\n",
      "epoch: 1 step 1500, loss is 0.09352534264326096\n",
      "epoch: 1 step 1625, loss is 0.025928258895874023\n",
      "epoch: 1 step 1750, loss is 0.0918595939874649\n",
      "epoch: 1 step 1875, loss is 0.20610764622688293\n",
      "Epoch time: 15709.893, per step time: 8.379, avg loss: 1.440\n",
      "************************************************************\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "from mindspore.nn.loss import SoftmaxCrossEntropyWithLogits\n",
    "\n",
    "if os.name == \"nt\":\n",
    "    # clean up old run files before in Windows\n",
    "    os.system('del/f/s/q *.ckpt *.meta')\n",
    "else:\n",
    "    # clean up old run files before in Linux\n",
    "    os.system('rm -f *.ckpt *.meta *.pb')\n",
    "\n",
    "lr = 0.01\n",
    "momentum = 0.9 \n",
    "\n",
    "# create the network\n",
    "network = LeNet5()\n",
    "\n",
    "# define the optimizer\n",
    "net_opt = nn.Momentum(network.trainable_params(), lr, momentum)\n",
    "\n",
    "# define the loss function\n",
    "net_loss = SoftmaxCrossEntropyWithLogits(is_grad=False, sparse=True, reduction='mean')\n",
    "\n",
    "# define the model\n",
    "model = Model(network, net_loss, net_opt, metrics={\"Accuracy\": Accuracy()} )\n",
    "\n",
    "epoch_size = 1\n",
    "mnist_path = \"./MNIST_Data\"\n",
    "# save the network model and parameters for subsequence fine-tuning\n",
    "config_ck = CheckpointConfig(save_checkpoint_steps=125, keep_checkpoint_max=16)\n",
    "# group layers into an object with training and evaluation features\n",
    "ckpoint_cb = ModelCheckpoint(prefix=\"checkpoint_lenet\", config=config_ck)\n",
    "# define step_loss dictionary for saving loss value and step number information\n",
    "step_loss = {\"step\": [], \"loss_value\": []}\n",
    "# save the steps and loss informations\n",
    "step_loss_info = StepLossInfo()\n",
    "\n",
    "repeat_size = 1\n",
    "train_net(model, epoch_size, mnist_path, repeat_size, ckpoint_cb, step_loss_info)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练完成后，能在Jupyter的工作路径上生成多个模型文件，名称具体含义`checkpoint_{网络名称}-{第几个epoch}_{第几个step}.ckpt`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 查看损失函数随着训练步数的变化情况"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYMAAAEWCAYAAACEz/viAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjMsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+AADFEAAAgAElEQVR4nO3dd5xU5dn/8c9FsQtYQAEVUMFYYhQwajSJjyZKTGKNCWps0RjboyQxjyXRaBJjjOVnLLFExRrBWNEoVqIRKyCggEoVUEBAqhRZuH5/3Gecs7MzszO7c2Zmd77v12tec8p9zrnmzO655r7vU8zdERGR2tam0gGIiEjlKRmIiIiSgYiIKBmIiAhKBiIigpKBiIigZCAlYGZ/MrMFZja3zNu91cwuKec2G2NmM8zsO2XcXk8zczNrV65tlloU/46VjqPWKRm0EuU+CMW2uy3wa2AXd986we2cbGavxqe5+xnu/sektiktU6X+F1o6JQNprh7AQnf/tNKBSG1rybWjaqBkUAPM7OdmNsXMPjOzYWbWLZpuZvb/zOxTM1tiZuPNbLdo3qFmNtHMlpnZx2Z2fpb1fgd4HuhmZsvN7G4zO8DMZmeU+/KXmpldZmYPmdm90bonmFn/WNltzexRM5tvZgvN7CYz2xm4Fdg32s7iqOzdZvanxj5nNM/N7Awzm2xmi8zsZjOzLJ+pm5mtNLPNY9P2jJrB2pvZDmb2UhTbAjN7wMw65djvmfHV2zfRth6JPut0Mzs3z3e4oZlda2YfRd/Vq2a2YazI8WY2M4rpt7Hlvm5mr5vZYjObE+3P9QrZL2bWNtrmgii+c+JNUmbW0czujNb7sYXmwrY54m9rZheb2dToex8d1SpTvpMjhrz7O/rbusDMxgOfm9mDwHbAk9Hfyv/l2qeSwd31agUvYAbwnSzTDwQWAH2B9YEbgVeieYcAo4FOgAE7A12jeXOAb0bDmwF9c2z3AGB2rvHM2IDLgFXAoUBb4ErgjWheW2Ac8P+AjYENgP2jeScDr2as927gT419zmi+A09Fn3U7YD4wIMdnegn4eWz8auDWaHhH4LvRNjoDrwDX5/isX8aXuW8IP8RGA5cC6wHbA9OAQ3LEdDPwH6B7tJ++EcXQM/ps/wA2BL4GrAZ2jpbrB+wDtIvKTgIGFbJfgDOAicA20d/AC1H5dtH8x4Hbou+qC/AW8Isc8f8GeBfYifC39jVgiwJiKGR/jwW2BTbM97+gVyPHkEoHoFeJvsjcyeBO4K+x8U2ANdGB4UDgw+hg0SZjuZnAL4AOjWz3ywNctvHM2AjJ4IXYvF2AldHwvtGBoF2W7ZxM/mSQ83NG406UWKLxh4ALc3ym04CXomEDZgHfylH2COCdHJ/1y/gy9w2wNzAzY10XAYOzbKMNsBL4WpZ5PaPPtk1s2lvAwBzxDgIei43n3C+EpPiL2LzvROXbAVsRks6GsfnHAiNybPcD4PAc84r5brLt758V8r+gV/6Xmolav27AR6kRd18OLAS6u/tLwE2EX53zzOx2M+sQFT2a8Ov9IzN72cz2LWFM8bOOVgAbRE0P2wIfuXtdE9aZ83Pm2e4mOdb1MKFJqhvwLcLB6r8AZtbFzIZEzSJLgfuBLZsQbw9C89ri1Au4mHCQzbQloZY0Nc/6sn42M+tjZk+Z2dwo3j9niTfXfulGSIQp8eEeQHtgTiz+2wg1hGy2bWL8hezvWUizKRm0fp8Q/nEBMLONgS2AjwHc/QZ37wfsCvQhVOdx97fd/XDCP/fjhF9rhfgc2Ci2vbaE6n0hZgHbWfaOwMZur5v3cxbD3RcDzwE/Bo4DHvToJyehWcuB3d29A/BTQu0hm3r7AoifbTULmO7unWKvTd390CzrWUBoWtuh2M8C3AK8D/SO4r04T7yZ5hCaiFLibfyzCDWDLWPxd3D3XXOsaxZNi7+Q/Z35t6FbMTeBkkHr0t7MNoi92gH/BE4xsz3MbH3CL8M33X2Gme1lZnubWXvCgWsVsNbM1jOz482so7uvAZYCawuM4UPCL/3vR+v9HaG9txBvEQ5AfzGzjaPPsF80bx6wTbzzM0POz1ngtrOt70RCDemfsembAsuBxWbWnSh55jAWONTMNjezrQlNNClvAUujzs8Now7W3cxsr8yVuPs64C7guqjTua2Z7Rt9zsZsSvj+lpvZV4AzC1gm5SHgPDPrHnXaXhCLaQ4hYV5rZh3MrE3U2fvtHOu6A/ijmfW2YHcz26LA+Avd3ynzCH0wUgQlg9blaULbcup1mbu/CFwCPEI40O4ADIzKdyB0PC4iNLEsBK6J5p0AzIiq5mcQfpE1yt2XAGcR/vk/JiSZ2XkXSi+7FvghodNwZrTcT6LZLwETgLlmtiDLsvk+Z1MMA3oD89x9XGz65YRO6iXAv4FH86zjPkKH+AzCgXNoLN7UZ90DmE749X8H0DHHus4ndMC+DXwGXEVh/7/nE2o3ywjf9dD8xev5RxT3eOAdwt9XHekfBicSOr8nEv6GHga65ljXdYTk8hwhOd1J6PBuTDH7O+VK4HdR81WDs+AkO0vXfkVEcjOz7xHOqurRaGFpcVQzEJGsouarQ82sXdRE83vgsUrHJclQzUBEsjKzjYCXga8Qmh3/DZzn7ksrGpgkQslARETUTCQiIuFKwhZnyy239J49e1Y6DBGRFmX06NEL3D3rdT8tMhn07NmTUaNGVToMEZEWxcw+yjVPzUQiIqJkICIiSgYiIoKSgYiIoGQgIiIoGYiICEoGIiKCkoGUy7Rp8NxzlY5CRHJQMqh1S5fCww+H4TFjoC564uTatXDnnbBmTWm207s3HHJI89axdi28/z689hrMnFmauEQEUDKonJEj4fHHc88fPx5uvz0Mz5oF+a64XrcOXn8dFi8Gd3j++fDuHg7o48fD/PnZlz3tNDjmGHjkEejXD373O/jzn6FduzDvr39tuMznn4df+pnWrIGJE+tPW70ann02xAjwwAMNl7vnHvjFL9Ljy5fD1Knhva4OBg0KB/8//xl23hn22w969AjJYfjw8DkBxo4N03J91lJatQoWLQrDc+fC9OnJb1MkSe7e4l79+vXzRNTVuc+Z4z5mjPull7pPmRKmL1rkft117ldf7d63r/trr7l37Oj++uvuI0a4r1vnPnSo+y23hOGVK90XLHCfOdN9gw3cn33WvXPncHj++ONQJnW4/stfwvuYMe4PP+z+m9+4P/poev7tt7v37x+GX3nF/a233AcOdD/ttFB+663TZbt0cR8wIAz36eNulp63ySbuZ52VHl++3P3009Pjv/lNejj+2n9/9+OOc5840X3wYPfddnNv3z7M++533U85xX3JkhDX/vuH6SNGuN92W/b1bb55eP/tb90/+sj9/PPrz7/33vR6wP2BB7KvJ/464oiwP8C9a9fwPmSI+wUXuPfq5b7LLu5nnun+1FPu3/ym+377ub/7bvgezzzT/Zhj3H//e/e333Y/9tiw/CGHuB90UBh++GH3O+5wHznSffHi8P2lvpMPPkjvjyVLwt/LI4+4H3VU2CeTJ9f/G1u50n3t2mT+fkUaAYzyHMfVFnkL6/79+3uT7k2U+nV5772wcmWY1rUrzJlT2gBFGrPhhqF5bv/9oUOHSkcjNcLMRrt7/2zzaquZ6LHH4Lbb0okAlAikMlauhO9/Hzp2DEmhHE1bInnUVjL43/8NbbsTJoR29FtugWuugUsugX33hb598y/fJsfuOuWUwmPYdtvCy8btvHPTlktSnz6h7b4a3XAD9OqVe37btuWLpTHHHANduoRGr7//PfTJiJRbrvajan4l1meQ8sUX7p9/7j52bBj/97/dn38+tBXHrVsXyqbMnRvK7rBDuq14wgT3m29Ol1m9OrSzT57s/swz6W3U1bm//37omxg61L1nT/fZs90ffDC0cc+fn17H8OH128zvv9/9kkvCurffPvRTrLdeug3e3f0b38je3n755e677hqGJ050nzEj9FOk+h3A/ZNPQr/Jtde6r1oV5u+8c9hH7qH/4bLL3Lt1C+X79Uuvf+ON08P/8z+hn+Lgg8P4oYfWjyW13fPOc7/qqvDZ430XqeE33nC/8srQln/22e6TJoV3cB83rv53FF//qlWhj+DXvw7f3QUXuD/5pPu8eeE7Oe640CcCoU/B3f2hh9y/9a30fp440f2kk8L4Cy+EfghwP/HE8H7CCaH822833P4tt4RtnHlm9u/ixhvD+1lnNenPVqQx5OkzqPiBvSmvxJNBSzBtmnvv3qEDNq6uLryWLQsH1DVrwvSFC8P4xx+HjvE33wyd5e7hYP/3v9dfz+zZ9RNdIdatC52jq1a577VX6ER2Tx9gU5Ytc7/++nRHaupgO21aiDeedHfYISSr1avdn3gi97ZXrXJ/+eWG01PJeMaMwj7DihXu06c3nL5oUTquL76o3zE8aVKYN2NGw332zjshUcc7jdeuDZ3XuTrEBw4sLFaRIuVLBrXVgSyVsXhx6JvJ1dQ1bx489RScemrDeevWhUNkNTXrlMr8+fDuu3DQQfWnH3883H9/ZWKSVk0dyFJZnTrl7/PYaqvsiQBCP01rTAQAnTvDgQfCkCH1p7drkQ8glBZOyUCk0n7yExgwID2uZCAVoGQgUg2OPz49vMEGlYtDapaSgUg16NQpPTx3buXikJqlZCBSDeJNQ488Urk4pGYpGYhUg802q3QEUuOUDESqwd57w6OPhuHevSsbi9QknbYgUi2OPBL69w+3phApM9UMRKpJ27bpBwyJlJGSgUg1adu2/l11RcpEzUQi1eS118L7lCmw446VjUVqimoGItVInchSZkoGItXq29+Gv/2t0lFIjVAyEKlWr7wCgwZVOgqpEUoGIiKiZCBSVbbZptIRSI1SMhCpJh9+WOkIpEYpGYhUkw03hEsvrXQUUoMSTQZmtq2ZjTCzSWY2wczOy1LGzOwGM5tiZuPNrG+SMYmISENJX3RWB/za3ceY2abAaDN73t0nxsp8D+gdvfYGboneRWrT4MGVjkBqUKI1A3ef4+5jouFlwCSge0axw4F7PXgD6GRmXZOMS6SqXX11pSOQGlS2PgMz6wnsCbyZMas7MCs2PpuGCQMzO93MRpnZqPnz5ycVpkjl7bZbpSOQGlSWZGBmmwCPAIPcfWnm7CyLeIMJ7re7e39379+5c+ckwhSpDuutV+kIpAYlngzMrD0hETzg7o9mKTIb2DY2vg3wSdJxiVSt9u0rHYHUoKTPJjLgTmCSu1+Xo9gw4MTorKJ9gCXuPifJuESqmmoGUgFJn020H3AC8K6ZjY2mXQxsB+DutwJPA4cCU4AVwCkJxyRS3TJrBpMn6y6mkrhEk4G7v0r2PoF4GQfOTjIOkRYlMxn06QMjRsABB1QkHKkNugJZpNq0y/IbbdKk8schNUXJQKTatG3bcJrlrWCLNJuSgUi1UTKQClAyEKk2bfRvKeWnvzqRaqOagVSAkoFItdGBXypAyUCkJVCCkIQpGYi0BEoGkjAlA5GWQMlAEqZkICIiSgYiLYJqBpIwJQMREVEyEGkRvMHznkRKSslApCVYt67SEUgrp2Qg0hIoGUjClAxEWgIlA0mYkoFIS6A+A0mYkoFIS6CagSRMyUCkGg0ZUn9cyUASpmQgUo169qw/rmQgCVMyEKlGmc80UJ+BJEzJQKQatWtXf1w1A0mYkoFINcqsGSgZSMKUDESqUefO9cfXrq1MHFIzlAxEqtHWW9cfV81AEqZkINISqGYgCVMyEGkJlAwkYUoGIi2BkoEkTMlApCVQn4EkTMlApCW4/npYtqzSUUgrpmQg0hKsWAGDBlU6CmnFlAxEWoqFCysdgbRiSgYiIpJsMjCzu8zsUzN7L8f8A8xsiZmNjV6XJhmPiIhk167xIs1yN3ATcG+eMv919x8kHIeIiOSRaM3A3V8BPktyGyI1Q7exlgRVQ5/BvmY2zsyeMbNdcxUys9PNbJSZjZo/f3454xMRafUqnQzGAD3c/WvAjcDjuQq6++3u3t/d+3fOvKOjSGu0336VjkBqSEWTgbsvdffl0fDTQHsz27KSMYlUjRdfrHQEUkMKTgZmtpWZ3Wlmz0Tju5jZqc3ZuJltbWYWDX89ikcnU4sArL9+/XH1GUiCiqkZ3A08C3SLxj8E8l4SaWYPAq8DO5nZbDM71czOMLMzoiI/At4zs3HADcBAd/3Fi2Slfw1JUDGnlm7p7g+Z2UUA7l5nZnlvpejuxzYy/ybCqaciIlJBxdQMPjezLQAHMLN9gCWJRCUiDek21pKgYmoGvwKGATuY2UigM6GZR0TKYc2aSkcgrVjBycDdx5jZt4GdAAM+cHf9dYqUyxJVxCU5BScDMzsxY1JfM8Pd891qQkRK5e23QydyOAFPpKSKaSbaKza8AXAQ4aIxJQORcvnii/qnnN51F0ydCldcUbmYpFWwpp7JaWYdgfvc/bDShtS4/v37+6hRo8q9WZHyy6wFLFoEnTo1nK/TTqUAZjba3ftnm9ecK5BXAL2bsbyIFGvFipAATjml0pFIK1NMn8GTRKeVEpLILsBDSQQlIjmsWBHe774bBg+uaCjSuhTTZ3BNbLgO+MjdZ5c4HhHJZ/XqSkcgrVQxp5a+nGQgIlIAXWsgCWk0GZjZMtLNQ/VmAe7uHUoelYhkp2QgCWm0A9ndN3X3DllemyoRiCRswgQYPjw9/vWvZy83cSLcq7O8pemKPrXUzLoQrjMAwN1nljqoxujUUqk52S40y3YBmk4xlTxKcmqpmR1mZpOB6cDLwAzgmZJEKCIiFVXMdQZ/BPYBPnT3XoQrkEcmEpWIiJRVMclgjbsvBNqYWRt3HwHskVBcIiJSRsVcZ7DYzDYBXgEeMLNPCdcbiIhIC1dMzeBwwi0ofgkMB6YCP0wiKBERKa9iaganA/+Krjq+J6F4RESkAoqpGXQAnjWz/5rZ2Wa2VVJBiYhIeRWcDNz9cnffFTgb6Aa8bGYvJBaZiIiUTVNuYf0pMBdYCHQpbTgiIlIJxVx0dqaZ/Qd4EdgS+Lm7755UYCIiUj7FdCD3AAa5+9hsM81sM3dfVJqwRESknIrpM7gwVyKIvFiCeESkVHr3hoED0+O33ALHH1+5eKSqNeexl5my3ElLRErivvsKKxe/Ud2UKTB0aHr8rLPgn/8sbVzSapQyGeh2iSJJ+elPG07LdidTkSYqZTIQkUrTLaylidRMJNKajB8fagxTp1Y6Emlhijm1dAczWz8aPsDMzjWzTrEiB5U8OhFJ23jjxssMHhzeH3882Vik1SmmZvAIsNbMdgTuBHoBX/ZGuftnJY5NROLuuKPwsmoukiIVkwzWuXsdcCRwvbv/EuiaTFgi0kCbAv5dlQSkiYp6uI2ZHQucBDwVTWtf+pBEJKu2bRsvo2QgTVRMMjgF2Be4wt2nm1kv4P58C5jZXWb2qZm9l2O+mdkNZjbFzMabWd8i4hGpLaoZSIKKuQJ5oruf6+4PmtlmwKbu/pdGFrsbGJBn/veA3tHrdOCWQuMRqTmqGUiCijmb6D9m1sHMNgfGAYPN7Lp8y7j7K0C+juXDgXs9eAPoZGbqhxDJRslAElRMM1FHd18KHAUMdvd+wHeauf3uwKzY+OxoWgNmdrqZjTKzUfPnz2/mZkVaIDUTSYKKSQbtol/tPybdgdxc2S5Uy/rX7O63u3t/d+/fuXPnEm1epAVRMpAEFZMM/gA8C0x197fNbHtgcjO3PxvYNja+DfBJM9cp0joVcy8iJQUpUjEdyP9y993d/cxofJq7H93M7Q8DTozOKtoHWOLuc5q5TpHapSQgTVTww23MbBvgRmA/QlPOq8B57j47zzIPAgcAW5rZbOD3RNcmuPutwNPAocAUYAXh9FURaSolA2miYp50Nphw+4ljovGfRtO+m2sBdz823wrd3YGzi4hBRPJJJYPbb69sHNLiFNNn0NndB7t7XfS6G1BPrki5rFzZeJk1a8L7lCnFrdu9fq2irg5uuy28S00oJhksMLOfmlnb6PVTYGFSgYlIhtWrGy9zzz2FrWvy5NAh/eqrYXzjjWGXXdLzb7kFzjgDbrqp+DilRSomGfyMcFrpXGAO8CPUxi9SPkcdBZtvXpp1vfBCeL8/uqPMypXw/vvp+Z9F14ouWlSa7UnVK+Zsopnufpi7d3b3Lu5+BOECNBEph3bt4P/+rzTr0iMzJUNzn3T2q5JEISIiFdXcZKCfFyItmU5FlUgxp5Zmo78kkWo3ciR061Z/WqHNREoWNaPRZGBmy8h+0Ddgw5JHJCKltf/+ueflOtirT6HmNNpM5O6bunuHLK9N3b25NQsRqYTUwf4f/6hsHFI1mttnICIirYCSgYiIKBmI1KR4n8CHH1YuDqkaSgYitW7x4kpHIFVAyUCk1uU7cyjX2UbTp8O112afV1cHTz6p01JbGCUDkZZkt91Ks554AmjKaaQDBsD558PcuQ3nXXklHHYYPFWqp+NKOSgZiLQk3/8+TJpU2nUW8mzlTEuWhPdsv/5nzAjvn37a5JCk/JQMRFqar3yltOvLVjPQRWc1R8lApBY11kxUivZ+9Rm0KEoGIrWuObUA1SpaDSUDkVpz1VX1D9jZ+gx0QK85SgYitebCC+uP68BfOZddBs89V+koACUDkdp06qnp4aYkg0L6Awops2wZ/O//wooVxcfQGlx+ORxySKWjAJQMRFqHq69u+rJNueis0PmNueYauOkmuOGG5q1Hmk3JQKTWNeeAvm5d7nmF1Djq6sL72rVNj0FKQslApNblO6A3prFE8sQTuvishVAyEGkNmtMJvPvuTV82XyJZvhyOOCLcukKqnpKBSGvQp09y6x4+PCSb6dMbzstXM0jNy3eLbF2YVjX02EqR1uCHP0xmvS+8AFOmhOE33oBevcJw6iCerWaQqqWk3gvpD9DprRWnmoGINJQ6OL/5Znra1KmwalX9cqmksGwZTJuWfV4hyeCee+Dpp0PCkYpQMhBpyWbMyH4b6aZas6bhtNRB/ZJL4Ljj6s9L1QwOOAB22CH7cmvWNH6Q//DDcEfWfffNPj911pEkRslApCXr0QO22qp061u5suG0hx5KDz/7bP15qQP+mDHhvW9f+O9/68+D3Af5QvoMJk+G9u1hyJDGy5rBCSc0Xq4aVFl/iZKBiKR17Biag3LJPIBl9hm88w588EH2sk01dmx4f/jhwsrff3/DaStWwFe/Cq+/XpqYSqGxU3rHjYOJE8sTC0oGIpJp1Kjc81IHsNSBPt8BvznXL8Sl+i+ak1zGjoX33oNf/ao0MRVi9eoQ+1/+kn1+Y/tnjz1g111LH1cOiScDMxtgZh+Y2RQzuzDL/JPNbL6ZjY1epyUdk0iL98EH8Pzzyaw730Eq84BcyKmlzVWKZJBatpxnLaWeBpfrWdGlSpYlkuippWbWFrgZ+C4wG3jbzIa5e2bdZ6i7n5NkLCKtSp8+yV1bUEwyyFc28+6ohawvm1Ikg1ScTXnEZ3PlSkBVlgyS3jNfB6a4+zR3/wIYAhye8DZFpDkWLMg9L/MAVo5O0KYmgzFjYMSI+suWo2YwbhxstlnjZ3lV2f2Ykr7orDswKzY+G9g7S7mjzexbwIfAL919VmYBMzsdOB1gu+22SyBUEQFg0KDc8zL7Ch55BHbbrenbKuTg3NRk0K9ferlyJoPrroPFi+GZZ/Jvs8ZqBtn2QuY3+iTQ0913B14A7sm2Ine/3d37u3v/zp07lzhMESlI5gHsssuS32ZL6jNwh3vvLWybNZYMZgPbxsa3AT6JF3D3he6+Ohr9B9Av4ZhEpJI6doSbbw7Dpegz+PDDxptkUsu2aROupSj0NNVixfskGvtsNZYM3gZ6m1kvM1sPGAgMixcws66x0cOASQnHJCKlVMxBzR2WLoVzijhfpLFksNNO0K1b/nWkYjSDX/8ajjkGXn218BiaorGawcKFyW6/SIkmA3evA84BniUc5B9y9wlm9gczOywqdq6ZTTCzccC5wMlJxiTSanXtGm4LUW7FHNSa0tRTSDNRoU9kMwu38ID0qZ9JaSwZfPxxstsvUuJ3LXX3p4GnM6ZdGhu+CLgo6ThEWr1PohbYpNvF+/evnwC6dCl82UKSwTXXwPnnp8eT6jModj99+mlpP2tqfvfuxcWREF2BLCLFGT266csWcmrqb34TkkG8aSdX2ULFk0Fj65k/H66/vn65t94K94B64IGmbTPf/CqhZCDS2vz+95WOILf4ATBfM82114YD8G23hbuZQjh/3yycztrU7RZSMzjhBPjlL8N9llLGjw/vqesWmrpNgJEjYdEiJQMRSdhll8HQoZWOIrv4AfA//2m8/EWxFuQ5c8L7j37U+HIHHph9u4XUDD77LLxnu212MQfwbB3r69bB/vvDwQcrGYhIGXzjG5WOILv4AbCxg6FZ7ttH5DrQpmT+gi+mZpCvbCmSAYSbAaaGUx3JM2eGJqpMS5aEu64mTMlApDVq27bSETTkDn/9a+Hl8yWD5csbTsv3AJzUQXzx4obPZEj53vfgiScaHvBXrUo/06EpySD++M8vvmgYE4SE0KNH9g7qTp1g++0L324TKRmItEbVmAweeKBhf0a+axTMcv96X7y44bRsT2nL3E78MZ6Z6x4+HI44ov787baDDTeE557LHm++02ozy266KfTunR6PJ4N4kshm3rxwSuzq1fnLNYOSgUhrVIm7czYm80yc+fPzJ4Mnnwync2aTLRkUUjOIiyeDbM1XZjAr4zZp8XJ33w1bbhk6trO58sr621m5Mn36b+a64rGcfHL2mwX26gWnnpp9WyVQhX8xItJshdYMdtwx2Tjihg+vP3766fmbXf74x9zziq0ZZB7Uof4BON4mn++U0Pvug4MOCsOp5qbGnkZmln76W1z8s8eT9z335D4jLFcTVwkoGYi0RoUmgwsuSDaOxjT1/jxHHhneX3stPS1fzeDssxtO++yz9G2kd989PT11kP788+zreuml8J5atpBa2K23NpwWvz9SZuLJ1TyW4AWFSgYirVGhyaCcT/7K5m9/a9pyqdM/99svPS1fMshm4MBwnyKAadPS01PJ4Kqr8i//r3+F9/vvh5dfhh//OHu5XB3hg/8SmVwAAA3ESURBVAfXL1MIJQMRKUqhyaAa+xYKtXRp/fGTTip+HUOGNJyWSgb//ndh63jqqXBPqFRyyJSvI7xYCX5fLfgvQURyqoVksPnm9cdTzTfFKNfTxnI9Bzkls+8kV/JQMhCRoqSSwYYb1u/gdIef/Sw9Hj/ovP9+eWIrlVIcyBcsCGf5xBVyLUG+zupMhdQKLr+8/vhNNzV9XU2kZCDSGrVpA1dcEc6r32KL+vOuvz49nDq49O0bngvQGjV2AB07tv54IcmgmFpIIQfwO+8sbF0J1gwSv4W1iFTIxReH91Rna8qmm6aHUweXKrtPTll98kn98ULOcCq2s7pUVDMQkSbbZJPc81LNSeuvX55YqlHqYTcpjV03APCDHxS+/lIewGfOLN26MigZiLR2662Xe97Xvga/+1313uW0HOIP0klCC+mkVzORSK3I9kjMNm3yX+krzddCkkHLiFJEmmfRovq3g9hmm8rFUmtKnQwee6y064uoZiBSCzp1yj690lcg14JJk0q7vswO7xJRzUCkFqWSgJJBy7PxxomsVslApBalOpVr+ZTSlmqjjRJZrZKBSC1KJYPMK2njt00ow9O1pAlUMxCRkkldV5D55Kz4rZx/8pP08MYbhwfSp+7y2dIMGlTpCEpHyUBESiZXMog/fvGii9LD114LW28N552XfGxJSD3/oDVQMhCRksmVDFLje+wRblsxfjx06JC+4rYpD6PZY4+mx1kq7dtXOoLSUTIQkZK57rpw9fFee9WfnkoGffqE969+FZYsge7dw3hTkkEhndTnnFP4+jLv8FmI1pQM1IEsIiXTr1+4W2fmr8xUMsh1r6KmJINc1zjEDRxY+PoOPLD4GNq1okuqVDMQkcTttlt4HzAg+/xUMthqq/S0CRPyr3PIkFAT+cMfwvMVskn9ct99dxg2DO64I/f6mnJFb7brKeKPnWxJlAxEJHH9+sHChXDccdnnd+wY3o88EhYvhpEjYZdd8q9z663hl7+ESy6B5cuzl0klg7Vr4Yc/zP/rvynJINuDcE4+ufj1VINcCbWZlAxEpL7Mx0nGdekCkyfDDTeExPCNbzQs8847uR8O39iBPNW/kK9cr17515FNc54/MHduw2n9+jV9fYXadtvs0xO6alzJQESKs+OODTtkr7oqPEzHPZw99ItfFLfOVAI644zwnnrOQvxBPAAjRoQmqi5dGq4j38334s1am2yS/5GZr75af3yDDdLDRx8d3gu55fcnn8C55zac/vOfwwMPNL58uZ8x4e4t7tWvXz8XkSo3ebL7O+80nB5ShvuJJ6aH3d0XLUqXmTkzTO/Wzf2ww+qXc3f/6lfD+CuvuF98cRju2tX9T39KlwX3d991Hz68/nbNGsYSf61eXX+8ri49vGqV+7hx9ZfdeWf3TTZpuB539/Hj6087/PD0tlNxv/xy9jh23TX79GYARnmO42riB25gAPABMAW4MMv89YGh0fw3gZ6NrVPJQKQFu/VW92HDwnCuA9ykSWF6nz7uV1wRhu+9Nz1/1iz3224Lw0uXhvknnxwO1JkH8pTUtFdfTU9LJZXMg23meNeu7kcfXT/G1Px580KSSI1fcon7AQc0LNemjfsXX6Sn19W5f/JJ/TIbbZQe3muv9PDll7fsZAC0BaYC2wPrAeOAXTLKnAXcGg0PBIY2tl4lA5FWYsIE90ceaTi9rs791FPd33vPfe1a97ffzr+e6dPDL3p399Gj3T/6yP2JJwqLYeTI9IG2W7cwDdz33DN9sM4G3LfZpv74aadlLwfu3bvnXtdFF4Uyw4eny0+e7H7uueGzuLv36OHetm1hnylnyLmTgYX5yTCzfYHL3P2QaPyiqGnqyliZZ6Myr5tZO2Au0NnzBNa/f38fNWpUYnGLSI1bvDictZOv3f7FF8OZVF27hnH37J27qWl77gljxmRf1xdfwFNPhbO0PvssnMLbuXP9MmvWhG3ke4xpI8xstLv3zzYv6Q7k7sCs2PjsaFrWMu5eBywBtshckZmdbmajzGzU/PnzEwpXRIRwoVxjHbgHHZROBJD7LJ/33w9XWD/+eO51rbceHHVUWMcWWzRMBBA67ZuRCBqTdDLItncyf/EXUgZ3v93d+7t7/87ZdpSISDXaaSe48UbYbrtKR5JX0slgNhA/WXYbIPOZbV+WiZqJOgKfJRyXiIjEJJ0M3gZ6m1kvM1uP0EE8LKPMMOCkaPhHwEv5+gtERKT0Er17k7vXmdk5wLOEM4vucvcJZvYHQq/2MOBO4D4zm0KoERRxxyoRESmFxG/l5+5PA09nTLs0NrwKOCbpOEREJDfdjkJERJQMREREyUBERFAyEBERSPZ2FEkxs/nAR01cfEtgQQnDSUK1x1jt8YFiLIVqjw+qP8Zqi6+Hu2e9ardFJoPmMLNRue7NUS2qPcZqjw8UYylUe3xQ/TFWe3xxaiYSERElAxERqc1kcHulAyhAtcdY7fGBYiyFao8Pqj/Gao/vSzXXZyAiIg3VYs1AREQyKBmIiEhtJQMzG2BmH5jZFDO7sEIxbGtmI8xskplNMLPzoumXmdnHZjY2eh0aW+aiKOYPzOyQMsU5w8zejWIZFU3b3MyeN7PJ0ftm0XQzsxuiGMebWd+EY9sptp/GmtlSMxtU6X1oZneZ2adm9l5sWtH7zMxOispPNrOTsm2rxDFebWbvR3E8Zmadouk9zWxlbH/eGlumX/T3MSX6HDke81WS+Ir+XpP8X88R49BYfDPMbGw0vez7sMlyPRy5tb0It9CeCmwPrAeMA3apQBxdgb7R8KbAh8AuwGXA+VnK7xLFuj7QK/oMbcsQ5wxgy4xpfwUujIYvBK6Khg8FniE8tW4f4M0yf69zgR6V3ofAt4C+wHtN3WfA5sC06H2zaHizhGM8GGgXDV8Vi7FnvFzGet4C9o3ifwb4XoLxFfW9Jv2/ni3GjPnXApdWah829VVLNYOvA1PcfZq7fwEMAQ4vdxDuPsfdx0TDy4BJNHwudNzhwBB3X+3u04EphM9SCYcD90TD9wBHxKbf68EbQCcz65ptBQk4CJjq7vmuSC/LPnT3V2j4lL5i99khwPPu/pm7LwKeBwYkGaO7P+fh+eMAbxCeSJhTFGcHd3/dw1Ht3tjnKnl8eeT6XhP9X88XY/Tr/sfAg/nWkeQ+bKpaSgbdgVmx8dnkPwgnzsx6AnsCb0aTzomq6nelmhOoXNwOPGdmo83s9GjaVu4+B0JSA7pUOEYID0OK/+NV0z6E4vdZpf9Of0b4lZrSy8zeMbOXzeyb0bTuUVwp5YixmO+1kvvwm8A8d58cm1Yt+zCvWkoG2drjKnZerZltAjwCDHL3pcAtwA7AHsAcQlUTKhf3fu7eF/gecLaZfStP2YrEaOFRqocB/4omVds+zCdXTBWL1cx+C9QBD0ST5gDbufuewK+Af5pZhwrEWOz3Wsnv+1jq/zipln3YqFpKBrOBbWPj2wCfVCIQM2tPSAQPuPujAO4+z93Xuvs64B+kmzEqEre7fxK9fwo8FsUzL9X8E71/WskYCYlqjLvPi2Ktqn0YKXafVSTWqKP6B8DxUbMFUfPLwmh4NKEdvk8UY7wpKdEYm/C9VmoftgOOAoamplXLPixELSWDt4HeZtYr+kU5EBhW7iCiNsU7gUnufl1seryN/UggdabCMGCgma1vZr2A3oSOpyRj3NjMNk0NEzoY34tiSZ3dchLwRCzGE6MzZPYBlqSaRhJW71dYNe3DmGL32bPAwWa2WdQccnA0LTFmNgC4ADjM3VfEpnc2s7bR8PaE/TYtinOZme0T/T2fGPtcScRX7Pdaqf/17wDvu/uXzT/Vsg8LUsne63K/CGdwfEjIzr+tUAz7E6qD44Gx0etQ4D7g3Wj6MKBrbJnfRjF/QBnOOCCchTEuek1I7StgC+BFYHL0vnk03YCboxjfBfqXIcaNgIVAx9i0iu5DQmKaA6wh/PI7tSn7jNBuPyV6nVKGGKcQ2thTf4+3RmWPjr7/ccAY4Iex9fQnHJSnAjcR3c0gofiK/l6T/F/PFmM0/W7gjIyyZd+HTX3pdhQiIlJTzUQiIpKDkoGIiCgZiIiIkoGIiKBkICIiKBmI5GVmv7Vwd9nx0V0n97Zwh9SNKh2bSCnp1FKRHMxsX+A64AB3X21mWxLugvka4bqABRUNUKSEVDMQya0rsMDdVwNEB/8fAd2AEWY2AsDMDjaz181sjJn9K7rvVOqZEFeZ2VvRa8do+jFm9p6ZjTOzVyrz0UTqU81AJIfooP4q4WrnF4Ch7v6ymc0gqhlEtYVHCVe/fm5mFwDru/sfonL/cPcrzOxE4Mfu/gMzexcY4O4fm1knd19ckQ8oEqOagUgO7r4c6AecDswHhprZyRnF9iE8ZGWkhadbnUR40E7Kg7H3faPhkcDdZvZzwoNYRCquXaUDEKlm7r4W+A/wn+gXfeZjKI3wMJpjc60ic9jdzzCzvYHvA2PNbA+P7mwpUimqGYjkYOFZy71jk/YAPgKWER5ZCuHJYPvF+gM2MrM+sWV+Ent/PSqzg7u/6e6XAguof7tlkYpQzUAkt02AGy08IL6OcHfP0wm3zn7GzOa4+/9ETUcPmtn60XK/I9wxE2B9M3uT8MMrVXu4OkoyRriT6biyfBqRPNSBLJKQeEdzpWMRaYyaiURERDUDERFRzUBERFAyEBERlAxERAQlAxERQclARESA/w+PWTK1VJLt7wAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "steps = step_loss[\"step\"]\n",
    "loss_value = step_loss[\"loss_value\"]\n",
    "steps = list(map(int, steps))\n",
    "loss_value = list(map(float, loss_value))\n",
    "plt.plot(steps, loss_value, color=\"red\")\n",
    "plt.xlabel(\"Steps\")\n",
    "plt.ylabel(\"Loss_value\")\n",
    "plt.title(\"Loss function value change chart\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从上面可以看出来大致分为三个阶段：\n",
    "\n",
    "阶段一：开始训练loss值在2.2上下浮动，训练收益感觉并不明显。\n",
    "\n",
    "阶段二：训练到某一时刻，loss值减少迅速，训练收益大幅增加。\n",
    "\n",
    "阶段三：loss值收敛到一定小的值后，loss值开始振荡在一个小的区间上无法趋0，再继续增加训练并无明显收益，至此训练结束。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  数据测试验证模型精度"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "搭建测试网络的过程主要为：\n",
    "\n",
    "1. 载入模型`.cptk`文件中的参数`param`；\n",
    "2. 将参数`param`载入到神经网络LeNet5中；\n",
    "3. 载入测试数据集；\n",
    "4. 调用函数`model.eval`传入参数测试数据集`ds_eval`，就生成模型`checkpoint_lenet-1_1875.ckpt`的精度值。\n",
    "\n",
    "> `dataset_sink_mode`表示数据集下沉模式，不支持CPU，所以这里设置成`False`。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "============== Starting Testing ==============\n",
      "============== Accuracy:{'Accuracy': 0.9553285256410257} ==============\n"
     ]
    }
   ],
   "source": [
    "# testing relate modules \n",
    "def test_net(network, model, mnist_path):\n",
    "    \"\"\"Define the evaluation method.\"\"\"\n",
    "    print(\"============== Starting Testing ==============\")\n",
    "    # load the saved model for evaluation\n",
    "    param_dict = load_checkpoint(\"checkpoint_lenet-1_1875.ckpt\")\n",
    "    # load parameter to the network\n",
    "    load_param_into_net(network, param_dict)\n",
    "    # load testing dataset\n",
    "    ds_eval = create_dataset(os.path.join(mnist_path, \"test\"))\n",
    "    acc = model.eval(ds_eval, dataset_sink_mode=False)\n",
    "    print(\"============== Accuracy:{} ==============\".format(acc))\n",
    "\n",
    "test_net(network, model, mnist_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "经过1875步训练后生成的模型精度超过95%，模型优良。\n",
    "我们可以看一下模型随着训练步数变化，精度随之变化的情况。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`acc_model_info`函数是将每125步的保存的模型，调用`model.eval`函数将测试出的精度返回到步数列表和精度列表，如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def acc_model_info(network, model, mnist_path, model_numbers):\n",
    "    \"\"\"Define the plot info method\"\"\"\n",
    "    step_list = []\n",
    "    acc_list = []\n",
    "    for i in range(1, model_numbers+1):\n",
    "        # load the saved model for evaluation\n",
    "        param_dict = load_checkpoint(\"checkpoint_lenet-1_{}.ckpt\".format(str(i*125)))\n",
    "        # load parameter to the network\n",
    "        load_param_into_net(network, param_dict)\n",
    "        # load testing dataset\n",
    "        ds_eval = create_dataset(os.path.join(mnist_path, \"test\"))\n",
    "        acc = model.eval(ds_eval, dataset_sink_mode=False)\n",
    "        acc_list.append(acc['Accuracy'])\n",
    "        step_list.append(i*125)\n",
    "    return step_list,acc_list\n",
    "\n",
    "# draw line chart according to training steps and model accuracy\n",
    "l1,l2 = acc_model_info(network, model, mnist_path, 15)\n",
    "plt.xlabel(\"Model of Steps\")\n",
    "plt.ylabel(\"Model accuracy\")\n",
    "plt.title(\"Model accuracy variation chart\")\n",
    "plt.plot(l1, l2, 'red')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从图中可以看出训练得到的模型精度变化分为三个阶段：1、缓慢上升，2、迅速上升，3、缓慢上升趋近于不到1的某个值时附近振荡，说明随着训练数据的增加，会对模型精度有着正相关的影响，但是随着精度到达一定程度，训练收益会降低。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 模型预测应用"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "我们尝试使用生成的模型应用到分类预测单个或者单组图片数据上，具体步骤如下："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 需要将要测试的数据转换成适应LeNet5的数据类型。\n",
    "2. 提取出`image`的数据。\n",
    "3. 使用函数`model.predict`预测`image`对应的数字。需要说明的是`predict`返回的是`image`对应0-9的概率值。\n",
    "4. 调用`plot_pie`将预测的各数字的概率显示出来。负概率的数字会被去掉。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "载入要测试的数据集并调用`create_dataset`转换成符合格式要求的数据集，并选取其中一组32张图片进行预测。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Row 1, column 7 is incorrectly identified as 2, the correct value should be 3 \n",
      "\n",
      "Row 4, column 3 is incorrectly identified as 0, the correct value should be 8 \n",
      "\n",
      "[2 7 7 0 6 3 2 3 2 5 2 1 8 7 8 3 0 5 2 1 0 8 2 2 1 8 0 3 6 8 8 2] <--Predicted figures\n",
      "[2 7 7 0 6 3 3 3 2 5 2 1 8 7 8 3 0 5 2 1 0 8 2 2 1 8 8 3 6 8 8 2] <--The right number\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 32 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "ds_test = create_dataset(test_data_path).create_dict_iterator()\n",
    "data = ds_test.get_next()\n",
    "images = data[\"image\"]\n",
    "labels = data[\"label\"]\n",
    "\n",
    "output =model.predict(Tensor(data['image']))\n",
    "prb = output.asnumpy()\n",
    "pred = np.argmax(output.asnumpy(), axis=1)\n",
    "err_num = []\n",
    "index = 1\n",
    "for i in range(len(labels)):\n",
    "    plt.subplot(4, 8, i+1)\n",
    "    color = 'blue' if pred[i] == labels[i] else 'red'\n",
    "    plt.title(\"pre:{}\".format(pred[i]), color=color)\n",
    "    plt.imshow(np.squeeze(images[i]))\n",
    "    plt.axis(\"off\")\n",
    "    if color == 'red':\n",
    "        index = 0\n",
    "        print(\"Row {}, column {} is incorrectly identified as {}, the correct value should be {}\".format(int(i/8)+1, i%8+1, pred[i], labels[i]), '\\n')\n",
    "if index:\n",
    "    print(\"All the figures in this group are predicted correctly!\")\n",
    "print(pred, \"<--Predicted figures\") \n",
    "print(labels, \"<--The right number\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构建一个概率分析的饼图函数。\n",
    "\n",
    "备注：`prb`为上一段代码中，存储这组数对应的数字概率。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Figure 1 probability of corresponding numbers [0-9]:\n",
      " [-0.48477417  2.0016153  11.054499    2.3544474  -2.7436607  -3.630352\n",
      " -3.7523592   0.9330094   2.6389365  -6.602851  ]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Figure 2 probability of corresponding numbers [0-9]:\n",
      " [-1.916862   -0.16948226 -0.2352289  -0.5903556   0.8726251  -0.41480547\n",
      " -3.0238853   4.210627   -0.70848167  1.8492212 ]\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# define the pie drawing function of probability analysis\n",
    "def plot_pie(prbs):\n",
    "    dict1 = {}\n",
    "    # remove the negative number and build the dictionary dict1. The key is the number and the value is the probability value\n",
    "    for i in range(10):\n",
    "        if prbs[i] > 0:\n",
    "            dict1[str(i)] = prbs[i]\n",
    "\n",
    "    label_list = dict1.keys()\n",
    "    size = dict1.values()\n",
    "    colors = [\"red\", \"green\", \"pink\", \"blue\", \"purple\", \"orange\", \"gray\"] \n",
    "    color = colors[: len(size)]\n",
    "    plt.pie(size, colors=color, labels=label_list, labeldistance=1.1, autopct=\"%1.1f%%\", shadow=False, startangle=90, pctdistance=0.6)\n",
    "    plt.axis(\"equal\")\n",
    "    plt.legend()\n",
    "    plt.title(\"Image classification\")\n",
    "    plt.show()\n",
    "    \n",
    "    \n",
    "for i in range(2):\n",
    "    print(\"Figure {} probability of corresponding numbers [0-9]:\\n\".format(i+1), prb[i])\n",
    "    plot_pie(prb[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上过程就是这次手写数字分类训练的全部体验过程。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
